package com.bruce.codeFactory.Thread.lock;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

/**
 * @author luotuan
 * @Description
 * @create 2019-02-19 22:57
 **/
public class BooleanLock implements Lock {
    private boolean initValue;
    private Collection<Thread> blockedThreadCollection = new ArrayList<>();
    private Thread currentThread;

    public BooleanLock() {
        this.initValue = false;
    }

    @Override
    public synchronized void lock() throws InterruptedException {
        while (initValue){
             blockedThreadCollection.add(Thread.currentThread());
             this.wait();
        }
        blockedThreadCollection.remove(Thread.currentThread());
        this.initValue = true;
        this.currentThread = Thread.currentThread();
    }

    @Override
    public synchronized void lock(long mills) throws InterruptedException, TimeoutException {
         if(mills<=0){
             lock();
         }
         long hasRemaining = mills;
         long endTime = System.currentTimeMillis()+mills;
         while (initValue){
             if(hasRemaining<0){
                 throw new TimeoutException("获取锁超时");
             }
             blockedThreadCollection.add(Thread.currentThread());
             this.wait(mills);
             hasRemaining = endTime-System.currentTimeMillis();
         }
         this.initValue = true;
         this.currentThread = Thread.currentThread();
    }

    @Override
    public synchronized void unlock() {
        if(currentThread == Thread.currentThread()){
            this.initValue = false;
            System.out.println(Thread.currentThread()+" release the lock monitor.");
            this.notifyAll();
        }
    }

    @Override
    public Collection<Thread> getBlockedThread() {
        return Collections.unmodifiableCollection(blockedThreadCollection);
    }

    @Override
    public int getBlockedSize() {
        return blockedThreadCollection.size();
    }
}
